﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using static NPOI.HSSF.Util.HSSFColor;

namespace DFGK_WMS.Repository
{
    public class TInstructRepository : BaseRepository<TInstruct>, ITInstructRepository
    {
        public TInstructRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }

        public List<TInstructDto> GetTInstructPage(out int totalCount,int? InstructType, int? Status, string? PalletBarcode, int pageIndex = 1, int pageSize = 10)
        {
            var query = Context.TInstructs.AsQueryable();
            var relist = Context.TReceivingOrderDetails.AsQueryable();
            var outlist = Context.TShippingOrderDetails.AsQueryable();
            // 添加条件判断
            if (InstructType.HasValue)
            {
                query = query.Where(t => t.InstructType == InstructType.Value);
            }

            if (Status.HasValue)
            {
                query = query.Where(t => t.Status == Status.Value);
            }

            if (!string.IsNullOrEmpty(PalletBarcode))
            {
                query = query.Where(t => t.PalletBarcode.Contains(PalletBarcode));
            }

            // 计算总条数
            totalCount = query.Count();
            List<TInstructDto> rilst = new List<TInstructDto>();           
            foreach (var item in query)
            {
                TInstructDto riobj = new TInstructDto();
                riobj.Id= item.Id;
                riobj.Status = GetStatusText(item.Status);
                riobj.InstructType = GetInstructTypeText(item.InstructType);
                riobj.WorkDeviceTypeName = item.WorkDeviceType == 1 ? "线体" : "AGV";
                riobj.Priority = item.Priority;
                riobj.FromLocation = item.FromLocation;
                riobj.ToLocation = item.ToLocation;
                riobj.Qty = item.Qty;
                riobj.PalletBarcode = item.PalletBarcode;
                riobj.StartTime= item.StartTime;
                riobj.EndTime= item.EndTime;            
                rilst.Add(riobj);
            }
            // 分页
            //var result = query
            //                  .Select(s => new TInstructDto()
            //                  {
            //                      Id = s.Id,
            //                      WarehouseCode = s.WarehouseCode,
            //                      Status = GetStatusText(s.Status),
            //                      InstructType = GetInstructTypeText(s.InstructType),
            //                      WorkDeviceType = s.WorkDeviceType,
            //                      Priority = s.Priority,
            //                      FromLocation = s.FromLocation,
            //                      ToLocation = s.ToLocation,
            //                      Qty = s.Qty,
            //                      StartTime = s.StartTime,
            //                      EndTime = s.EndTime,
            //                      RelatedOrderId = s.RelatedOrderId,
            //                      RelatedOrderDetailId = s.RelatedOrderDetailId,                                
            //                  })
            //                  .ToList();
            rilst = rilst.OrderByDescending(x=>x.StartTime).Skip((pageIndex-1)*pageSize).Take(pageSize).ToList();
            return rilst;
        }
        private string GetStatusText(int status)
        {
            string statusText;
            switch (status)
            {
                case 0:
                    statusText = "创建";
                    break;
                case 1:
                    statusText = "待执行";
                    break;
                case 2:
                    statusText = "执行中";
                    break;
                case 3:
                    statusText = "搬运完成";
                    break;
                case 4:
                    statusText = "处理完成";
                    break;
                case 5:
                    statusText = "执行异常";
                    break;
                case 6:
                    statusText = "已强制取消任务";
                    break;
                default:
                    statusText = "未知状态";
                    break;
            }

            return statusText;
        }
        private string GetInstructTypeText(int instructType)
        {
            string instructTypeText;
            switch (instructType)
            {
                case 1:
                    instructTypeText = "上架";
                    break;
                case 2:
                    instructTypeText = "下架";
                    break;
                case 3:
                    instructTypeText = "移位";
                    break;
                case 4:
                    instructTypeText = "盘点";
                    break;
                default:
                    instructTypeText = "未知指令类型";
                    break;
            }

            return instructTypeText;
        }

        public bool DelTInstruct(int id)
        {
            try
            {
                var instruct = Context.TInstructs.FirstOrDefault(x => x.Id == id);
                if (instruct == null)
                {
                    throw new Exception("找不到该数据");
                }
                Context.Remove(instruct);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {

                throw;
            }

        }

        public bool UpdStatus(int id, out string msg)
        {
            try
            {
                var obj=Context.TInstructs.FirstOrDefault(s=>s.Id == id);
                if (obj == null)
                {
                    msg = "找不到此id对应的数据";
                    return false;
                }
                //该指令操作的货物
                var huoCount = Context.TInventoryDetails.Where(s=>s.PalletBarcode==obj.PalletBarcode).Count();
                if (huoCount <= 0)
                {
                    msg = "库存明细数据不存在";
                    return false;
                }
                msg = "成功";
                obj.Status = 3;
                Context.TInstructs.Update(obj);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 撤销指令
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool CancelInstruct(int id, out string message)
        {
            message = "";
            var instructobj = Context.TInstructs.Find(id);
            if (instructobj==null)
            {
                message = "找不到该指令！";
                return false;
            }
            bool result = false;
            switch (instructobj.InstructType)
            {
                case 1:
                    result = CancelRevingOrder(id,out message);
                    break;
                case 2:
                    break;
                case 3:
                    break;
            }
            return result;
        }

        public List<InstructMaterDto> GetInstructMater(int id)
        {
            List<InstructMaterDto> instructMaterDtolist = new List<InstructMaterDto>();
            var tinstructobj = Context.TInstructs.Find(id);
            if (tinstructobj==null)
            {
                return instructMaterDtolist;
            }
            string? palletBarcode = "";
            var invobjlist = Context.TInventory.AsNoTracking();
            var receiobj = Context.TReceivingOrderDetails.Find(tinstructobj.RelatedOrderId);
            var shipplockobj = Context.TShippingLockCells.FirstOrDefault(x => x.OrderDetailId == tinstructobj.RelatedOrderId);
            InstructMaterDto instructmaterdtoobj = new InstructMaterDto();
            switch  (tinstructobj.InstructType)
            {
                case 1:
                    if(receiobj!=null)
                    {
                        instructmaterdtoobj.MaterName = receiobj.MaterialName;
                        instructmaterdtoobj .MaterNum= receiobj.StackedQty;
                        instructMaterDtolist.Add(instructmaterdtoobj);
                    }
                    break;
                case 2:
                    if(shipplockobj!=null)
                    {
                        instructmaterdtoobj.MaterName = shipplockobj.MaterialName;
                        instructmaterdtoobj.MaterNum = shipplockobj.OutQty;
                        instructMaterDtolist.Add(instructmaterdtoobj);
                    }
                    break;
                case 3:
                    palletBarcode = invobjlist.FirstOrDefault(x => x.RelatedOrderDetailId == tinstructobj.RelatedOrderId)?.PalletBarcode;
                    if (invobjlist.Any())
                    {
                        instructMaterDtolist = invobjlist.Where(x => x.PalletBarcode == palletBarcode).Select(x => new InstructMaterDto
                        {
                            MaterName = x.MaterialName,
                            MaterNum = tinstructobj.Qty
                        }).ToList();
                    }
                    break;
            }
            return instructMaterDtolist;
        }
        /// <summary>
        /// 撤销指令入库
        /// </summary>
        /// <param name="id">关联id</param>
        /// <returns></returns>
        private bool CancelRevingOrder(int id,out string message)
        {
            message = "";
            var instructobj = Context.TInstructs.Find(id);
            if (instructobj == null)
            {
                message = "找不到该指令！";
                return false;
            }
            //删除指令
            Context.TInstructs.Remove(instructobj);
            var reveingor = Context.TReceivingOrderDetails.Find(instructobj.RelatedOrderId);
            if(reveingor==null)
            {
                message = "找不到入库单！";
                return false;
            }
            //删除入库单
            Context.TReceivingOrderDetails.Remove(reveingor);
            var stackingstorageobj = Context.TStackingStorages.Find(instructobj.StackingStorageId);
            if(stackingstorageobj==null)
            {
                message = "找不到组垛信息！";
                return false;
            }
            //删除组垛信息
            Context.TStackingStorages.Remove(stackingstorageobj);
            //上架单
            var putobj = Context.TPutawayOrders.FirstOrDefault(x => x.RelatedOrderDetailId == reveingor.Id && x.Status == 4);
            if(putobj!=null)
            {
                //删除上架单
                Context.TPutawayOrders.Remove(putobj);
                var putdeobj = Context.TPutawayOrderDetails.Where(x => x.PutawayOrderId == putobj.Id);
                if(putdeobj.Any())
                    Context.TPutawayOrderDetails.RemoveRange(putdeobj);
            }      
            var rebvingbillobj = Context.TReceivingBills.Find(reveingor.ReceivingBillId);
            if(rebvingbillobj==null)
            {
                message = "找不到收货单信息！";
                return false;
            }
            //收货单恢复状态和数量
            rebvingbillobj.Status = 0;
            rebvingbillobj.BeginDate = null;
            rebvingbillobj.EndDate = null;
            var rebvingbilldetailsobj = Context.TReceivingBillDetails.FirstOrDefault(x=>x.BillId== rebvingbillobj.Id);
            if (rebvingbilldetailsobj == null)
            {
                message = "找不到收货单明细信息！";
                return false;
            }
            rebvingbilldetailsobj.ReceivedQty = 0;
            //库存
            var invobj = Context.TInventories.FirstOrDefault(x => x.RelatedOrderDetailId == reveingor.Id);
            if (invobj==null)
            {
                message = "找不到库存！";
                return false;
            }
            Context.TInventories.Remove(invobj);
            //库存明细
            var indvobj = Context.TInventoryDetails.FirstOrDefault(x => x.InventoryId == invobj.Id);
            if(indvobj!=null)
            {
                Context.TInventoryDetails.Remove(indvobj);
            }
            //仓位
            var cellobj = Context.TCells.FirstOrDefault(x => x.Code == invobj.LocationCode);
            if(cellobj!=null)
            {
                cellobj.FullStatus = 0;
                cellobj.IsLock = false;
                cellobj.BusinessType = 0;
                cellobj.Status = 1;
                Context.TCells.Update(cellobj);
            }

            return Context.SaveChanges()>0;
        }
    }
}
